/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package javacroft.facade;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import javacroft.business.*;
import javacroft.dataccess.DataAccessFactory;

/**
 * Classe manager des structures
 * @author Fabien RETIF
 * @version 1.0
 */
public class StructureManager {

    private List<Departement> lesDepartements = null;
    private DataAccessFactory service = null;
    private Departement departementCourant = null;
    private Annee anneeCourante = null;
    private List<Annee> lesAnneesHistorique = null;
    private Semestre semestreCourant = null;
    private UE ueCourante = null;
    private ECUE ecueCourante = null;
    private List<ECUE> lesECUECourantes = null;
    private List<UE> lesUECourantes = null;

    public StructureManager(DataAccessFactory daf)
    {
        service = daf;
        lesDepartements = new ArrayList<Departement>();
        lesAnneesHistorique = new ArrayList<Annee>();
        lesECUECourantes = new ArrayList<ECUE>();
        lesUECourantes = new ArrayList<UE>();
    }

    /**
     * Procédure de mise à jour du structure manager
     * @param departement : index du département choisi parmi la liste des départements du structure manager | -1 si aucun n'est choisi
     * @param anneeChoisies : index de l'année choisie parmi le département courant dans structure manager | -1 si aucune n'est choisie
     * @param semestreChoisi : index du semestrechoisi parmi l'année courante dans structure manager | -1 si aucun n'est choisi
     * @param UEChoisie : index de l'UE choisie parmi le semestre courant dans structure manager | -1 si aucune n'est choisie
     * @param ECUEChoisie : index de l'ECUE choisie parmi l'UE courante dans structure manager | -1 si aucune n'est choisie
     * @throws Exception : Exception venant des couches inférieures
     */
    public void updateStructure(int departement, int anneeChoisies, int semestreChoisi, int UEChoisie, int ECUEChoisie) throws Exception
    {
        if(departement != -1)
        {
            departementCourant = lesDepartements.get(departement); //On charge le département

            if(anneeChoisies != -1)
            {
                anneeCourante = departementCourant.getLesAnnees().get(anneeChoisies);
            }
            else
            {
                anneeCourante = null;
            }
        }
        else
        {
            departementCourant = null;
        }

        // On a choisi au moins un département et une année
        if(anneeCourante != null)
        {
            if(semestreChoisi == -1 && UEChoisie == -1 && ECUEChoisie == -1)
            {
                //000
                //On a choisi aucun semestre, ni UE, ni ECUE
                semestreCourant = null;
                ueCourante = null;
                ecueCourante = null;

                lesUECourantes = getLesUEAnnee(); //On charge les UE courantes de l'année
                lesECUECourantes = getLesECUEAnnee(); //On charges les ECUEs courante de l'année
            }
            else if(semestreChoisi == -1 && UEChoisie == -1 && ECUEChoisie != -1)
            {
                //001
                //On a choisi une ecue, aucun semestre, ni ue
                semestreCourant = null;
                ueCourante = null;
                ecueCourante = getLesECUEAnnee().get(ECUEChoisie);

                lesUECourantes = getLesUEAnnee(); //On charge les UE courantes de l'année
                lesECUECourantes = getLesECUEAnnee(); //On charges les ECUEs de l'année

            }
            else if(semestreChoisi == -1 && UEChoisie != -1 && ECUEChoisie == -1)
            {
                //010
                //On a choisi une UE, aucun semestre, ni ecue
                semestreCourant = null;
                ueCourante = getLesUEAnnee().get(UEChoisie);
                ecueCourante = null;

                lesUECourantes = getLesUEAnnee(); //On charge les UE courantes de l'année
                lesECUECourantes = getLesECUEAnnee(); //On charges les ECUEs de l'année

            }
            else if(semestreChoisi == -1 && UEChoisie != -1 && ECUEChoisie != -1)
            {
                //011
                //On a pas choisi le semestre mais choisi ue, ecue
                semestreCourant = null;
                ueCourante = getLesUEAnnee().get(UEChoisie);
                ecueCourante = getLesECUEAnnee().get(ECUEChoisie);

                lesUECourantes = getLesUEAnnee(); //On charge les UE courantes de l'année
                lesECUECourantes = getLesECUEAnnee(); //On charges les ECUEs de l'année
            }
            else if(semestreChoisi != -1 && UEChoisie == -1 && ECUEChoisie == -1)
            {
                //100
                //On a choisi un semestre, aucun ue, ni ecue
                semestreCourant = anneeCourante.getLesSemestres().get(semestreChoisi);
                ueCourante = null;
                ecueCourante = null;

                lesUECourantes = semestreCourant.getLesUE(); //On charge les UE courantes du semestre
                lesECUECourantes = getLesECUESemestre(); //On charges
            }
            else if(semestreChoisi != -1 && UEChoisie != -1 && ECUEChoisie == -1)
            {
                //110
                //On a choisi un semestre, une ue, mais pas ecue
                semestreCourant = anneeCourante.getLesSemestres().get(semestreChoisi);
                ueCourante = semestreCourant.getLesUE().get(UEChoisie);
                ecueCourante = null;

                lesUECourantes = semestreCourant.getLesUE();
                lesECUECourantes = ueCourante.getLesECUE();
            }
            else if(semestreChoisi != -1 && UEChoisie == -1 && ECUEChoisie != -1)
            {
                //101
                //On a choisi un semestre et ecue mais pas ue
                semestreCourant = anneeCourante.getLesSemestres().get(semestreChoisi);
                ueCourante = null;
                ecueCourante = getLesECUESemestre().get(ECUEChoisie);

                lesUECourantes = semestreCourant.getLesUE();
                lesECUECourantes = getLesECUESemestre();
            }
            else
            {
                //111
                //On a choisi un semestre, une ue et ecue
                semestreCourant = anneeCourante.getLesSemestres().get(semestreChoisi);
                ueCourante = semestreCourant.getLesUE().get(UEChoisie);
                ecueCourante = ueCourante.getLesECUE().get(ECUEChoisie);
                lesECUECourantes = ueCourante.getLesECUE();
                lesUECourantes = semestreCourant.getLesUE();
            }
        }
    }


    /**
     * Fonction qui retourne la liste des départements
     * @return Liste de départements
     */
    public List<Departement> getLesDepartements()
    {
        return lesDepartements;
    }

    /**
     * @param lesDepartements the lesDepartements to set
     */
    public void setLesDepartements(List<Departement> lesDepartements)
    {
        this.lesDepartements = lesDepartements;
    }

    /**
     * Procédure qui charge les départements en mémoire depuis la couche persistence
     * @param lesDepts : Liste des départements à charger
     * @throws Exception : Exception venant des couches inférieures
     */
    public void chargerLesDepartements(List<String> lesDepts) throws Exception
    {
        Iterator iter = lesDepts.iterator();
        Departement deptCourant = null;

        while (iter.hasNext())
        {
             lesDepartements.add(new Departement((String)iter.next()));
        }

        if(!lesDepartements.isEmpty())
        {
            //On instancie les années des départements
            iter = lesDepartements.iterator();

            while (iter.hasNext())
            {
                deptCourant = (Departement)iter.next();
                deptCourant.setLesAnnees(getLesAnnees(deptCourant));
            }
        }

    }
    /**
     * Fonction qui retourne les années du département donné en paramètre
     * @param unDept
     * @return Liste d'années
     * @throws Exception : Exception venant des couches inférieures
     */
    public List<Annee> getLesAnnees(Departement unDept) throws Exception
    {
        List<Map> lesDonnees = service.getLesAnnees(unDept.getNom());
        List<Annee> lesAnnees = new ArrayList<Annee>();

        Iterator iter = lesDonnees.iterator();
        Annee anneeCourant = null;

        while (iter.hasNext())
        {
            lesAnnees.add(new Annee((String)((HashMap)iter.next()).get("unNom")));
        }

        if(!lesAnnees.isEmpty())
        {
            //On instancie les années des départements
            iter = lesAnnees.iterator();

            while (iter.hasNext())
            {
                anneeCourant = (Annee)iter.next();
                anneeCourant.setLesSemestres(getLesSemestres(anneeCourant));
            }
        }

        return lesAnnees;
    }

    /**
     * Fonction qui retourne les semestres de l'année donnée en paramètre
     * @param anneeCourant
     * @return Liste de semestres
     * @throws Exception : Exception venant des couches inférieures
     */
    public List<Semestre> getLesSemestres(Annee anneeCourant) throws Exception
    {
        List<Map> lesDonnees = service.getLesSemestres(anneeCourant.getNom());
        List<Semestre> lesSemestres = new ArrayList<Semestre>();

        Iterator iter = lesDonnees.iterator();
        Semestre semCourant = null;
        HashMap<String,String> infoTemp = null;

        while (iter.hasNext())
        {
            infoTemp = (HashMap)iter.next();
            lesSemestres.add(new Semestre(Integer.parseInt((infoTemp.get("unNumero").toString())),infoTemp.get("unCodeApogee")));
        }

        if(!lesSemestres.isEmpty())
        {
            //On instancie les années des départements
            iter = lesSemestres.iterator();

            while (iter.hasNext())
            {
                semCourant = (Semestre)iter.next();
                semCourant.setLesUE(getLesUE(semCourant));
            }
        }

        return lesSemestres;
    }

    /**
     * Fonction qui retourne les UE du semestre passé en paramètre
     * @param semestreCourant
     * @return Liste d'UE
     * @throws Exception : Exception venant des couches inférieures
     */
    public List<UE> getLesUE(Semestre semestreCourant) throws Exception
    {
        List<Map> lesDonnees = service.getLesUE(semestreCourant.getCodeApogee());
        List<UE> lesUE = new ArrayList<UE>();

        Iterator iter = lesDonnees.iterator();
        HashMap<String,String> infoTemp = null;
        UE ueCourant = null;

        while (iter.hasNext())
        {
            infoTemp = (HashMap)iter.next();
            lesUE.add(new UE(infoTemp.get("unNom"),Integer.parseInt(infoTemp.get("nbCredit"))));
        }

        if(!lesUE.isEmpty())
        {
            //On instancie les années des départements
            iter = lesUE.iterator();

            while (iter.hasNext())
            {
                ueCourant = (UE)iter.next();
                ueCourant.setLesECUE(getLesECUE(ueCourant));
            }
        }

        return lesUE;
    }

    /**
     * Fonction qui retourne les ECUE de l'UE passée en paramètre
     * @param ueCourant
     * @return Liste d'ECUE
     * @throws Exception : Exception venant des couches inférieures
     */
    public List<ECUE> getLesECUE(UE ueCourant) throws Exception
    {
        List<Map> lesDonnees = service.getLesECUE(ueCourant.getNom());
        List<ECUE> lesECUE = new ArrayList<ECUE>();

        Iterator iter = lesDonnees.iterator();
        HashMap<String,String> infoTemp = null;

        while (iter.hasNext())
        {
            infoTemp = (HashMap)iter.next();
            lesECUE.add(new ECUE(infoTemp.get("unNom"),Float.valueOf(infoTemp.get("unCoeff"))));
        }

        return lesECUE;
    }

    /**
     * @return the departementCourant
     */
    public Departement getDepartementCourant()
    {
        return departementCourant;
    }

    /**
     * @param departementCourant the departementCourant to set
     */
    public void setDepartementCourant(Departement departementCourant)
    {
        this.departementCourant = departementCourant;
    }

    /**
     * @return the anneeCourante
     */
    public Annee getAnneeCourante()
    {
        return anneeCourante;
    }

    /**
     * @param anneeCourante the anneeCourante to set
     */
    public void setAnneeCourante(Annee anneeCourante)
    {
        this.anneeCourante = anneeCourante;
    }

    /**
     * @return the semestreCourant
     */
    public Semestre getSemestreCourant()
    {
        return semestreCourant;
    }

    /**
     * @param semestreCourant the semestreCourant to set
     */
    public void setSemestreCourant(Semestre semestreCourant)
    {
        this.semestreCourant = semestreCourant;
    }

    /**
     * @return the ueCourante
     */
    public UE getUeCourante()
    {
        return ueCourante;
    }

    /**
     * @param ueCourante the ueCourante to set
     */
    public void setUeCourante(UE ueCourante)
    {
        this.ueCourante = ueCourante;
    }

    /**
     * @return the ecueCourante
     */
    public ECUE getEcueCourante()
    {
        return ecueCourante;
    }

    /**
     * @param ecueCourante the ecueCourante to set
     */
    public void setEcueCourante(ECUE ecueCourante)
    {
        this.ecueCourante = ecueCourante;
    }

    /**
     * @return the lesECUECourantes
     */
    public List<ECUE> getLesECUECourantes()
    {
        return lesECUECourantes;
    }

    /**
     * @param lesECUECourantes the lesECUECourantes to set
     */
    public void setLesECUECourantes(List<ECUE> lesECUECourantes)
    {
        this.lesECUECourantes = lesECUECourantes;
    }

    /**
     * @return the lesUECourantes
     */
    public List<UE> getLesUECourantes()
    {
        return lesUECourantes;
    }

    /**
     * @param lesUECourantes the lesUECourantes to set
     */
    public void setLesUECourantes(List<UE> lesUECourantes)
    {
        this.lesUECourantes = lesUECourantes;
    }
    /**
     * Fonction qui retourne les UE de l'année courante - Pré-requis l'attribut anneeCourante != null
     * @return Liste d'UE
     */
    private List<UE> getLesUEAnnee()
    {
        List<UE> lesUE = new ArrayList<UE>();

        Iterator iter = anneeCourante.getLesSemestres().iterator();

        while (iter.hasNext())
        {
            lesUE.addAll(((Semestre)iter.next()).getLesUE());
        }

        return lesUE;
    }

    /**
     * Fonction qui retourne les ECUE de l'année courante - Pré-requis l'attribut anneeCourante != null
     * @return Liste d'ECUE
     */
    private List<ECUE> getLesECUEAnnee()
    {
        List<ECUE> lesECUE = new ArrayList<ECUE>();

        Iterator iterUE = getLesUEAnnee().iterator();

        while(iterUE.hasNext())
        {
            lesECUE.addAll(((UE)iterUE.next()).getLesECUE());
        }

        return lesECUE;
    }

    /**
     * Fonction qui retourne les ECUE du semestre courant - Pré-requis l'attribut semestreCourant != null
     * @return Liste d'ECUE
     */
    private List<ECUE> getLesECUESemestre()
    {
        List<ECUE> lesECUE = new ArrayList<ECUE>();

        Iterator iterUE = semestreCourant.getLesUE().iterator();

        while(iterUE.hasNext())
        {
            lesECUE.addAll(((UE)iterUE.next()).getLesECUE());
        }

        return lesECUE;
    }

   /**
    * Fonction qui retourne VRAI si l'année courante à changer
    * @return VRAI si anneeCourante à changer, FAUX sinon
    */
    public boolean isChangeAnnee()
    {
        if(anneeCourante != null)
        {
            if(!lesAnneesHistorique.contains(anneeCourante))
            {
                lesAnneesHistorique.add(anneeCourante);
                return true;
            }
        }

        return false;
    }

    void setAction(Enseignant monEnseignant, String action) {
        
    }
}
